/*
Copyright 2009 Jeff Carnes

This file is part of Fluant.

Fluant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

Fluant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.amiasleep.fluant.flaPublisher;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.util.FileUtils;

import com.amiasleep.fluant.FluantException;
import com.amiasleep.fluant.flaPublisher.io.SWFOutput;
import com.amiasleep.fluant.jsfl.JSFLRunner;



public class FlaPublisherTask extends Task {

	private int timeout = FLAPublisher.DEFAULT_TIMEOUT;
	protected File _fla;
	protected SWFOutput _swf;
	protected Profile originalProfile;
	protected boolean closeFile = false;
	protected boolean hideFlash = false;
	protected boolean closeFlash = false;
	protected boolean failOnError = true;
	protected boolean failOnWarning = false;
	
	

	public FlaPublisherTask() {}

	

	public void execute() throws BuildException {
		if(_fla == null)
		{
			throw new BuildException("The 'file' attribute must be specified");
		}
		
		log("Publishing " + _fla.getAbsolutePath());
		
		try {
			FLAPublisher publisher = new FLAPublisher(timeout);
			publisher.closeFLAWhenFinished = closeFile;
			publisher.hideFlashWhenFinished = hideFlash;
			publisher.failOnWarning = failOnWarning;
			publisher.run(_fla, originalProfile);
		} catch (Exception ex) {
			if(failOnError)
			{
				throw new BuildException(ex);
			}
			else
			{
				log(ex.toString());
			}
		}
	}
	
	

	public void setFile(File fla) {
		_fla = fla;
		
		// Export the profile now as this property will be set prior
		// to the "createXXX" methods being called, which need to return
		// profiles with the existing settings from the FLA, which are
		// then overridden by the publish types, such as <swf>.
		try
		{
			originalProfile = exportProfile(_fla);
		}
		catch(ExportProfileException epe)
		{
			throw new BuildException(epe);
		}
	}
	
	
	
	public void setTimeout(int duration)
	{
		timeout = duration;
	}
	
	
	
	public void setCloseFile(boolean doClose)
	{
		closeFile = doClose;
	}
	
	
	
	public void setCloseFlash(boolean doClose)
	{
		closeFlash = doClose;
	}
	
	
	
	public void setHideFlash(boolean doHide)
	{
		hideFlash = doHide;
	}
	
	
	
	public void setFailOnError(boolean doFail)
	{
		failOnError = doFail;
	}
	
	
	
	public void setFailOnWarning(boolean doFail)
	{
		failOnWarning = doFail;
	}
	
	

	public SWFOutput createSwf() {
		// Return the profile we've already created so that its
		// values can be overridden by values in the build
		return originalProfile.getSwf();
	}
	
	

	protected Profile exportProfile(File fla) throws ExportProfileException
	{
		Profile retVal = null;
		log("Creating publish profile from " + fla.getAbsolutePath());
		
		try
		{
			// Create JSFL to export the existing profile for the FLA passed in
			File exportedProfile = File.createTempFile("fluantExportedProfile", ".xml");
			File exportJSFL = File.createTempFile("fluantExport", ".jsfl");
			Writer out = new FileWriter(exportJSFL);
			PublishJSFLIO.writeExportJSFL(fla, exportedProfile, out);
			
			// Run the JSFL we just created
			JSFLRunner runner = new JSFLRunner(exportJSFL); // @TODO: Let account for time needed to open Flash
			runner.hideFlashWhenFinished = false;
			runner.run();

			// Create a Profile instance from the XML we just exported
			retVal = ProfileIO.read(exportedProfile);
		}
		catch(IOException ioe)
		{
			throw new ExportProfileException(ioe);
		}
		catch(FluantException fe)
		{
			throw new ExportProfileException(fe);
		}

		return retVal;
	}
}


@SuppressWarnings("serial")
class ExportProfileException extends Exception
{
	public ExportProfileException(final Throwable cause)
	{
		super(cause);
	}
}
